import React, { ReactElement } from 'react';
import { Surface, Shape, Path } from '@react-native-community/art';
// import PropTypes from 'prop-types';

export default (props: any): ReactElement => {
  const {
    boxWidth = 60, // 容器宽度
    boxHeight = 60, // 容器高度
    boxStyle, // 容器样式
    outerRadius, // 圆弧半径
    startAngle, // 开始角度
    endAngle, // 结束角度
    originX = 0, // 左边的距离 不是圆心的X
    originY = 0, // 上部的距离 不是圆心的Y
    innerRadius = 0, // 内部半径-画弧
    ...otherProps
  } = props;

  const circleRadians = Math.PI * 2;
  const radiansPerDegree = Math.PI / 180;

  const degreesToRadians = (degrees: number): number => {
    if (degrees !== 0 && degrees % 360 === 0) {
      // 360, 720, etc.
      return circleRadians;
    }
    return (degrees * radiansPerDegree) % circleRadians;
  };

  const createCirclePath = (or: number, ir: number): any => {
    const path = new Path();

    path
      .move(originX, or + originY)
      .arc(or * 2, 0, or)
      .arc(-or * 2, 0, or);

    if (ir) {
      path
        .move(or - ir, 0)
        .counterArc(ir * 2, 0, ir)
        .counterArc(-ir * 2, 0, ir);
    }

    path.close();

    return path;
  };

  const createArcPath = (or: number, ir: number): any => {
    const path = new Path();

    // angles in radians
    const sa = degreesToRadians(startAngle);
    const ea = degreesToRadians(endAngle);

    // central arc angle in radians
    const ca = sa > ea ? circleRadians - sa + ea : ea - sa;

    // cached sine and cosine values
    const ss = Math.sin(sa);
    const es = Math.sin(ea);
    const sc = Math.cos(sa);
    const ec = Math.cos(ea);

    // cached differences
    const ds = es - ss;
    const dc = ec - sc;
    const dr = ir - or;

    // if the angle is over pi radians (180 degrees)
    // we will need to let the drawing method know.
    const large = ca > Math.PI;

    // TODO (sema) Please improve theses comments to make the math
    // more understandable.
    //
    // Formula for a point on a circle at a specific angle with a center
    // at (0, 0):
    // x = radius * Math.sin(radians)
    // y = radius * Math.cos(radians)
    //
    // For our starting point, we offset the formula using the outer
    // radius because our origin is at (top, left).
    // In typical web layout fashion, we are drawing in quadrant IV
    // (a.k.a. Southeast) where x is positive and y is negative.
    //
    // The arguments for path.arc and path.counterArc used below are:
    // (endX, endY, radiusX, radiusY, largeAngle)

    path
      .move(originX, originY) // move to starting point
      .arc(or * ds, or * -dc, or, or, large) // outer arc
      .line(dr * es, dr * -ec); // width of arc or wedge

    if (ir) {
      path.counterArc(ir * -ds, ir * dc, ir, ir, large); // inner arc
    }

    return path;
  };

  // sorted radii
  const ir = Math.min(innerRadius, outerRadius);
  const or = Math.max(innerRadius, outerRadius);

  let path;
  if (endAngle >= startAngle + 360) {
    path = createCirclePath(or, ir);
  } else {
    path = createArcPath(or, ir);
  }

  return (
    <Surface width={boxWidth} height={boxHeight} style={boxStyle}>
      <Shape d={path} {...otherProps} />
    </Surface>
  );
};
